<?php

namespace App\Http\Controllers\Operation\Model;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use App\Services\ModelCategoryService;
use App\Services\ModelClassService;
use App\ModelClass;

class ModelClassController extends Controller
{
    private $modelCategoryService = null;
    private $modelClassService = null;

    public function __construct(ModelCategoryService $modelCategoryService,
        ModelClassService $modelClassService)
    {
        $this->modelCategoryService = $modelCategoryService;
        $this->modelClassService = $modelClassService;
    }

    public function index()
    {
        return view('operation.model.class.class', [
            'categories' => $this->modelCategoryService
                ->getCategories(['parentId'=>''], false)
        ]);
    }

    public function query(Request $request)
    {
        return $this->modelClassService->getClasses($request->all());
    }

    public function createNew()
    {
        return view('operation.model.class.create', [
            'categories' => $this->modelCategoryService->getAllLeafCategoriesEntity()
        ]);
    }

    public function saveNewClass(Request $request)
    {
        $input = $request->all();

        $this->validateWhenCreateNew($input);

        $propItems = json_decode($input['props'], true);

        $this->modelClassService->saveNewClass($input, $propItems);

        return response()->json([
            'Success' => true,
            'Message' => '新增品类成功',
        ]);
    }

    public function editClass($classId)
    {
        $class = ModelClass::findOrFail($classId);

        return view('operation.model.class.create', [
            'class' => $class,
            'categories' => $this->modelCategoryService->getAllLeafCategoriesEntity()
        ]);
    }

    public function saveUpdateClass(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdate($input);

        $propItems = json_decode($input['props'], true);

        $this->modelClassService->saveUpdateClass($input, $propItems);

        return response()->json([
            'Success' => true,
            'Message' => '修改品类成功',
        ]);
    }

    public function delete(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDeleteClass($input);

        $this->modelClassService->deleteClass($input['id']);

        return response()->json([
            'Success' => true,
            'Message' => '删除品类成功',
        ]);
    }

    private function validateWhenCreateNew($input)
    {
        return Validator::make($input, [
            'code' => 'required|max:100|unique:model_classes,code',
            'name' => 'required|max:50|unique:model_classes,name',
            'category_id' => [
                Rule::in(collect($this->modelCategoryService->getAllLeafCategoriesEntity())->pluck('id')->toArray())
            ],
            'sort_order' => 'required|numeric'
        ], [
            'code.required' => '品类代码不可为空',
            'code.max' => '品类代码长度不可超过:max',
            'code.unique' => '品类代码不可重复',
            'name.required' => '品类名称不可为空',
            'name.max' => '品类名称长度不可超过:max',
            'name.unique' => '品类名称不可重复',
            'category_id.in' => '传入的目录id不合法，只能是无下级分类的叶子级类目',
            'sort_order.required' => '必须传入同级排序号',
            'sort_order.numeric' => '同级排序号必须为数字'
        ])->after(function ($validator) use ($input){

            if (array_key_exists('props', $input)) {
                if (!empty($input['props'])) {
                    try {
                        $props = json_decode($input['props'], true);

                        $regex = '/^(([0-9a-zA-Z]+):([[\x{4e00}-\x{9fa5}0-9a-zA-Z]+),)*([0-9a-zA-Z]+):([[\x{4e00}-\x{9fa5}0-9a-zA-Z]+)$/ui';
                        $index = 1;
                        foreach ($props as $prop) {
                            if ($prop['name'] == '') {
                                $validator->errors()->add('props_name_illegal', '第'.$index.'个属性名称为空');
                            }
                            if (!preg_match($regex, $prop['value'])) {
                                $validator->errors()->add('props_value_illegal', '第'.$index.'个属性值格式错误，无法正确解析');
                            }

                            $index++;
                        }
                    } catch (Exception $ex) {
                        $validator->errors()->add('props_illegal', '参数格式错误');
                    }

                }
            } else {
                $validator->errors()->add('no_props', '没有传入参数');
            }

        })->validate();
    }

    private function validateWhenSaveUpdate($input)
    {
        return Validator::make($input, [
            'code' => [
                'required',
                'max:100',
                Rule::unique('model_classes')->where(function ($query) use($input) {
                    $query->where('code', $input['code'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'name' => [
                'required',
                'max:50',
                Rule::unique('model_classes')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('id', '<>', $input['id']);
                })
            ],
            'category_id' => [
                Rule::in(collect($this->modelCategoryService->getAllLeafCategoriesEntity())->pluck('id')->toArray())
            ],
            'sort_order' => 'required|numeric'
        ], [
            'code.required' => '品类代码不可为空',
            'code.max' => '品类代码长度不可超过:max',
            'code.unique' => '已经存在其它相同代码的品类',
            'name.required' => '品类名称不可为空',
            'name.max' => '品类名称长度不可超过:max',
            'name.unique' => '已经存在其它重名名称的品类',
            'category_id.in' => '传入的目录id不合法，只能是无下级分类的叶子级类目',
            'sort_order.required' => '必须传入同级排序号',
            'sort_order.numeric' => '同级排序号必须为数字'
        ])->after(function ($validator) use ($input){

            if (array_key_exists('props', $input)) {
                if (!empty($input['props'])) {
                    try {
                        $props = json_decode($input['props'], true);

                        $regex = '/^(([0-9a-zA-Z]+):([[\x{4e00}-\x{9fa5}0-9a-zA-Z]+),)*([0-9a-zA-Z]+):([[\x{4e00}-\x{9fa5}0-9a-zA-Z]+)$/ui';
                        $index = 1;
                        foreach ($props as $prop) {
                            if ($prop['name'] == '') {
                                $validator->errors()->add('props_name_illegal', '第'.$index.'个属性名称为空');
                            }
                            if (!preg_match($regex, $prop['value'])) {
                                $validator->errors()->add('props_value_illegal', '第'.$index.'个属性值格式错误，无法正确解析');
                            }

                            $index++;
                        }
                    } catch (Exception $ex) {
                        $validator->errors()->add('props_illegal', '参数格式错误');
                    }

                }
            } else {
                $validator->errors()->add('no_props', '没有传入参数');
            }

        })->validate();
    }

    private function validateWhenDeleteClass($input)
    {
        return Validator::make($input, [
                'id' => 'required|exists:model_classes,id'
            ], [
                'id.required' => '必须传入模型品类ID',
                'id.exists' => '该模型品类ID参数有误，不存在'
            ])->after(function ($validator) use($input) {
                if ($this->modelClassService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该品类存在其它关联，不可删除');
                }
            })->validate();
    }
}
